package com.seecen.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seecen.common.BaseResponse;
import com.seecen.common.ResultUtils;
import com.seecen.exception.ErrorCode;
import com.seecen.exception.ThrowUtils;
import com.seecen.pojo.dto.AdminLoginDTO;
import com.seecen.pojo.dto.AdminRegDTO;
import com.seecen.pojo.dto.UserDto;
import com.seecen.pojo.dto.UserReg;
import com.seecen.pojo.entity.User;
import com.seecen.pojo.vo.AdminLoginVO;
import com.seecen.pojo.vo.AdminRegVO;
import com.seecen.service.UserService;
import com.seecen.mapper.UserMapper;
import com.seecen.utils.JwtHelper;
import com.seecen.utils.MD5Utils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;

/**
* @author 小辛
* @description 针对表【allmaster_user(用户表)】的数据库操作Service实现
* @createDate 2025-10-17 12:38:49
*/
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{
    @Resource
    private UserMapper userMapper;
    @Resource
    private JwtHelper jwtHelper;

    @Override
    public BaseResponse login(UserDto userDto) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUseraccount, userDto.getUserAccount());
        User dbUser = userMapper.selectOne(wrapper);

        // 添加调试信息
        log.info("=== 登录调试信息 ===");
        log.info("输入账号: {}", userDto.getUserAccount());
        log.info("输入密码: {}", userDto.getUserPwd());

        if (dbUser != null) {
            log.info("数据库密码: {}", dbUser.getUserpassword());
            log.info("数据库密码长度: {}", dbUser.getUserpassword().length());
            log.info("用户角色: {}", dbUser.getUserrole());
            log.info("用户状态: {}", dbUser.getStatus()); // 添加状态调试信息

            // 判断账户是否已注销
            if (dbUser.getStatus() != null && dbUser.getStatus() == 2) {
                log.info("登陆失败：账户已注销，用户名={}", userDto.getUserAccount());
                return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "账户已注销，无法登录");
            }

            // 判断账户是否被禁用
            if (dbUser.getStatus() != null && dbUser.getStatus() == 1) {
                log.info("登陆失败：账户已被禁用，用户名={}", userDto.getUserAccount());
                return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "账户已被禁用，请联系管理员");
            }

            // 对输入密码进行MD5加密，然后与数据库比较
            String encryptedInputPwd = MD5Utils.encrypt(userDto.getUserPwd());
            log.info("MD5加密后输入密码: {}", encryptedInputPwd);
            log.info("密码匹配结果: {}", dbUser.getUserpassword().equals(encryptedInputPwd));

            // 添加角色判断 - 只允许user角色登录
            if (dbUser.getUserrole() == null) {
                log.info("登陆失败：用户角色未定义，用户名={}", userDto.getUserAccount());
                return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "用户角色未定义");
            }

            // 只允许角色为 "user" 的用户登录
            if (!"user".equals(dbUser.getUserrole())) {
                log.info("登陆失败：用户角色无权限登录，用户名={}, 角色={}", userDto.getUserAccount(), dbUser.getUserrole());
                return ResultUtils.error(ErrorCode.NO_AUTH_ERROR, "只有普通用户角色可以登录");
            }

            if (dbUser.getUserpassword().equals(encryptedInputPwd)) {
                // 更新登录时间
                User updateUser = new User();
                updateUser.setId(dbUser.getId());
                updateUser.setCreatetime(new Date()); // 设置当前时间为登录时间

                // 执行更新操作
                int updateResult = userMapper.updateById(updateUser);
                log.info("更新登录时间结果: {}", updateResult > 0 ? "成功" : "失败");

                // 重新查询用户信息，获取最新的登录时间
                dbUser = userMapper.selectById(dbUser.getId());

                // 登录成功逻辑
                String token = jwtHelper.createToken(Long.valueOf(dbUser.getId()));
                HashMap<String, Object> map = new HashMap<>();
                map.put("token", token);
                map.put("id", dbUser.getId());
                map.put("useraccount", dbUser.getUseraccount());
                map.put("username", dbUser.getUsername());
                map.put("userrole", dbUser.getUserrole()); // 返回用户角色到前端
                map.put("phonenumber", dbUser.getPhonenumber());
                map.put("useravatar", dbUser.getUseravatar());
                map.put("logintime", dbUser.getCreatetime()); // 返回最新的登录时间

                log.info("登陆成功，用户名={}, 角色={}", userDto.getUserAccount(), dbUser.getUserrole());
                return ResultUtils.success(map);
            }
        }

        log.info("登陆失败：用户名或密码错误，用户名={}", userDto.getUserAccount());
        return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "用户名或密码错误");
    }


    @Override
    public BaseResponse register(UserReg userReg) {
        // 校验用户是否存在
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("useraccount", userReg.getUserAccount());
        User existingUser = userMapper.selectOne(wrapper);

        if (!ObjectUtil.isNull(existingUser)) {
            return ResultUtils.error(ErrorCode.FORBIDDEN_ERROR, "用户已存在");
        }

        // 创建 User 实体
        User user = new User();
        user.setUseraccount(userReg.getUserAccount());
        user.setUserpassword(MD5Utils.encrypt(userReg.getUserPwd()));
        user.setUsername(userReg.getUserName());
        user.setPhonenumber(userReg.getUserPhone());

        // 存储图片URL而不是Base64数据
        if (ObjectUtil.isNotEmpty(userReg.getUserAvatar())) {
            user.setUseravatar(userReg.getUserAvatar()); // 存储文件URL
        } else {
            user.setUseravatar(""); // 或者设置默认头像URL
        }

        int result = userMapper.insert(user);

        if (result > 0) {
            return ResultUtils.success("注册成功");
        } else {
            return ResultUtils.error(ErrorCode.OPERATION_ERROR, "注册失败");
        }
    }
    @Override
    public BaseResponse deleteAccount(Long userId) {
        try {
            // 检查用户是否存在
            User user = userMapper.selectById(userId);
            if (user == null) {
                return BaseResponse.error("用户不存在");
            }

            // 检查用户状态
            if (user.getStatus() == 2) {
                return BaseResponse.error("账户已注销");
            }

            // 执行注销操作
            user.setStatus(2); // 标记为已注销
            userMapper.updateById(user);

            return BaseResponse.success("账户注销成功");

        } catch (Exception e) {
            return BaseResponse.error("注销失败: " + e.getMessage());
        }
    }
    @Override
    public BaseResponse<AdminLoginVO> getAdminLogin(AdminLoginDTO adminLoginDTO) {
        //1.校验参数
        if (adminLoginDTO == null || adminLoginDTO.getUseraccount() == null || adminLoginDTO.getUseraccount().trim().length() == 0){
            ThrowUtils.throwIf(true, ErrorCode.PARAMS_ERROR);
        }
        //2.查询是否有该用户根据账号查询数据库
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUseraccount, adminLoginDTO.getUseraccount()));
        ThrowUtils.throwIf(user == null, ErrorCode.PARAMS_ERROR);

        // 添加角色校验 - 只允许admin角色登录（必须在密码校验之前）
        if (!"admin".equals(user.getUserrole())) {
            log.info("管理员登录失败：用户角色不是admin，用户名={}, 角色={}", adminLoginDTO.getUseraccount(), user.getUserrole());
            ThrowUtils.throwIf(true, ErrorCode.PARAMS_ERROR);
        }

        //3.校验md5密码
        String md5Password = MD5Utils.encrypt(adminLoginDTO.getUserpassword());
        ThrowUtils.throwIf(!user.getUserpassword().equals(md5Password), ErrorCode.PARAMS_ERROR);

        AdminLoginVO adminVO = new AdminLoginVO();
        BeanUtil.copyProperties(user, adminVO);
        //4.返回结果
        //生成token
        adminVO.setToken(jwtHelper.createToken(user.getId()));

        log.info("管理员登录成功，用户名={}", adminLoginDTO.getUseraccount());
        return ResultUtils.success(adminVO);
    }

    @Override
    public BaseResponse<AdminRegVO> getAdminRegister(AdminRegDTO adminRegDTO) {
        //1.校验参数
        if (adminRegDTO == null || adminRegDTO.getUseraccount() == null || adminRegDTO.getUseraccount().trim().length() == 0){
            ThrowUtils.throwIf(true, ErrorCode.PARAMS_ERROR);
        }
        //2.对用户密码加密
        String md5Password = MD5Utils.encrypt(adminRegDTO.getUserpassword());
        adminRegDTO.setUserpassword(md5Password);
        //3.查询是否已经存在该用户
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUseraccount, adminRegDTO.getUseraccount()));
        ThrowUtils.throwIf(user != null, ErrorCode.PARAMS_ERROR);
        //4.插入用户
        user = new User();
        BeanUtil.copyProperties(adminRegDTO, user);
        user.setUserrole("admin");
        userMapper.insert(user);

        //5.返回结果

        AdminRegVO adminRegVO = new AdminRegVO();
        BeanUtil.copyProperties(user, adminRegVO);
        return ResultUtils.success(adminRegVO);
    }
    @Override
    public BaseResponse resetAccount(UserDto userDto) {
        // 1. 校验用户名是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, userDto.getUserAccount());
        User dbUser = userMapper.selectOne(queryWrapper);

        if (ObjectUtil.isNull(dbUser)) {
            log.info("密码重置失败：用户不存在，用户名={}", userDto.getUserAccount());
            return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR);
        }

        // 2. 校验新密码是否与原密码一致
        String newPwdEncrypted = MD5Utils.encrypt(userDto.getUserPwd());
        if (newPwdEncrypted.equals(dbUser.getUserpassword())) {
            log.info("密码重置失败：新密码与原密码一致，用户名={}", userDto.getUserAccount());
            return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR);
        }

        // 3. 更新密码
        dbUser.setUserpassword(newPwdEncrypted);
        int rows = userMapper.updateById(dbUser);

        if (rows > 0) {
            log.info("密码重置成功：用户名={}", userDto.getUserAccount());
            return ResultUtils.success("密码重置成功");
        } else {
            log.info("密码重置失败：数据库更新失败，用户名={}", userDto.getUserAccount());
            return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR);
        }
    }


}




